#!/usr/bin/python

import pprint
import math

from sys import argv

# Some globals
diceSides = 6
debug = False

pp = pprint.PrettyPrinter(indent=4)

def getProbDicts(params):

    # Obtain a dict of all possible outcomes
    atkOutcomes = getRawOutcomes(params['atkDice'])

    # Determine the probabilities of specific MoS values
    getRangeResults(params['threshold'], atkOutcomes, params['modifier'])


def getRangeResults(threshold, atkResults, atkMod):
    results = {}
    count = 0
    maxRes = 0
    for atkDiceRes in atkResults:
        atkRes = 0
        if atkDiceRes != 0:
            atkRes = atkDiceRes + atkMod
            
        result = 0
        if atkRes > threshold:
            result = atkDiceRes

        count = count + 1
        if result in results:
            results[result] = results[result] + 1
        else:
            results[result] = 1

        if debug:
            print "%i vs. (%i %+i = %i) -> %i" % (
                threshold, 
                atkDiceRes, atkMod, atkRes,
                result
                )
    
    checkCount = 0    
    for x in results.iterkeys():
        y = results[x]
        prob = (float(results[x]) / float(count)) * 100.0
        if debug:
            print "  MoS %i has %i occurances (%2.3f)" % (x, y, prob)
        results[x] = prob

        checkCount = checkCount + y
    
    for x in range(0, maxRes + 1, 1):
        if x not in results:
            results[x] = 0

    print "Results as percentages are:"
    pp.pprint(results)

    return results

def getRawOutcomes(numDice):
    outcomes = []
    # Generate the raw list that contains all possible outcomes
    for x in range(1, numDice+1):
        outcomes = appendDiceSides(outcomes, diceSides)
    
    # For each element, reduce it to a pre-modifier value
    results = []
    for x in outcomes:
        res = 0
        for y in x:
            if y == 6 and res >= 6:
                res = res + 1
            elif y > 1 and y > res:
                res = y
        results.append(res)
        if debug:
            print "Raw Outcome of %s has result %i " % (x, res)

    return results

def appendDiceSides(diceList, diceSides):

    if len(diceList) is 0:
        for x in range(1, diceSides+1):
            diceList.append([x])
        return diceList

    newList = []
    for y in diceList:
        # y is an element of list type
        for x in range(1, diceSides+1):
            z = y[:]
            z.append(x)
            newList.append(z)

    return newList

if __name__ == '__main__':
    params = {
        'threshold': 4,
        'atkDice': 2,
        'modifier' : 0,
    }

    if len(argv) >= 2:
        params['threshold'] = int(argv[1])
    if len(argv) >= 3:
        params['atkDice'] = int(argv[2])
    if len(argv) >= 4:
        params['modifier'] = int(argv[3])

    print "Calculating %iD%i%+i vs. threshold %i" % (params['atkDice'], diceSides, params['modifier'], params['threshold'])
    probDict = getProbDicts(params)

